﻿using System;
using System.Diagnostics;

namespace HEFramework
{
    /// <summary>
    ///
    /// 日志调用包装接口
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-11-30 10:23:41
    /// ----------------------------------------
    /// </summary>
    public static class Log
    {
        [Conditional("DEBUG_SHOW")]
        public static void Trace(string _msg)
        {
            Logger.Instance.Trace(_msg);
        }

        [Conditional("DEBUG_SHOW")]
        public static void Debug(string _msg)
        {
            Logger.Instance.Debug(_msg);
        }

        public static void Info(string _msg)
        {
            Logger.Instance.Info(_msg);
        }

        [Conditional("DEBUG_SHOW")]
        public static void Warning(string _msg)
        {
            Logger.Instance.Warning(_msg);
        }

        public static void Error(string _msg)
        {
            Logger.Instance.Error(_msg);
        }

        public static void Error(Exception _msg)
        {
            Logger.Instance.Error(_msg);
        }

        [Conditional("DEBUG_SHOW")]
        public static void Console(string _msg)
        {
            Logger.Instance.Console(_msg);
        }
    }


    /// <summary>
    ///
    /// 输出日志接口
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-11-30 10:12:08
    /// ----------------------------------------
    /// </summary>
    public interface ILog
    {
        void Trace(string _message);
        void Warning(string _message);
        void Info(string _message);
        void Debug(string _message);
        void Error(string _message);
        void Trace(string _message, params object[] _args);
        void Warning(string _message, params object[] _args);
        void Info(string _message, params object[] _args);
        void Debug(string _message, params object[] _args);
        void Error(string _message, params object[] _args);
    }


    /// <summary>
    ///
    /// Unity用的输出日志
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-11-30 10:11:50
    /// ----------------------------------------
    /// </summary>
    public class UnityLog : ILog
    {
        public void Trace(string _message)
        {
            UnityEngine.Debug.Log(_message);
        }

        public void Debug(string _message)
        {
            UnityEngine.Debug.Log(_message);
        }

        public void Info(string _message)
        {
            UnityEngine.Debug.Log(_message);
        }

        public void Warning(string _message)
        {
            UnityEngine.Debug.LogWarning(_message);
        }

        public void Error(string _message)
        {
            UnityEngine.Debug.LogError(_message);
        }

        public void Error(Exception _e)
        {
            UnityEngine.Debug.LogException(_e);
        }

        public void Trace(string _message, params object[] _args)
        {
            UnityEngine.Debug.LogFormat(_message, _args);
        }

        public void Warning(string _message, params object[] _args)
        {
            UnityEngine.Debug.LogWarningFormat(_message, _args);
        }

        public void Info(string _message, params object[] _args)
        {
            UnityEngine.Debug.LogFormat(_message, _args);
        }

        public void Debug(string _message, params object[] _args)
        {
            UnityEngine.Debug.LogFormat(_message, _args);
        }

        public void Error(string _message, params object[] _args)
        {
            UnityEngine.Debug.LogErrorFormat(_message, _args);
        }
    }


    /// <summary>
    ///
    /// 日志输出器
    /// 
    /// ----------------------------------------
    /// 作者 hep
    /// 创建时间：2023-11-30 10:12:57
    /// ----------------------------------------
    /// </summary>
    public class Logger : Singleton<Logger>, ISingletonAwake
    {
        private ILog iLog;

        public ILog ILog
        {
            set { this.iLog = value; }
        }

        private const int TRACE_LEVEL = 1;
        private const int DEBUG_LEVEL = 2;
        private const int INFO_LEVEL = 3;
        private const int WARNING_LEVEL = 4;

        public void Awake()
        {
            iLog = new UnityLog();
        }

        private bool CheckLogLevel(int _level)
        {
            return DEBUG_LEVEL <= _level;
        }

        public void Trace(string _msg)
        {
            if (!CheckLogLevel(DEBUG_LEVEL))
            {
                return;
            }

            StackTrace st = new StackTrace(2, true);
            this.iLog.Trace($"{_msg}\n{st}");
        }

        public void Debug(string _msg)
        {
            if (!CheckLogLevel(DEBUG_LEVEL))
            {
                return;
            }

            this.iLog.Debug(_msg);
        }

        public void Info(string _msg)
        {
            if (!CheckLogLevel(INFO_LEVEL))
            {
                return;
            }

            this.iLog.Info(_msg);
        }

        public void TraceInfo(string _msg)
        {
            if (!CheckLogLevel(INFO_LEVEL))
            {
                return;
            }

            StackTrace st = new StackTrace(2, true);
            this.iLog.Trace($"{_msg}\n{st}");
        }

        public void Warning(string _msg)
        {
            if (!CheckLogLevel(WARNING_LEVEL))
            {
                return;
            }

            this.iLog.Warning(_msg);
        }

        public void Error(string _msg)
        {
            StackTrace st = new StackTrace(2, true);
            this.iLog.Error($"{_msg}\n{st}");
        }

        public void Error(Exception _e)
        {
            if (_e.Data.Contains("StackTrace"))
            {
                this.iLog.Error($"{_e.Data["StackTrace"]}\n{_e}");
                return;
            }

            string str = _e.ToString();
            this.iLog.Error(str);
        }

        public void Trace(string _message, params object[] _args)
        {
            if (!CheckLogLevel(TRACE_LEVEL))
            {
                return;
            }

            StackTrace st = new StackTrace(2, true);
            this.iLog.Trace($"{string.Format(_message, _args)}\n{st}");
        }

        public void Warning(string _message, params object[] _args)
        {
            if (!CheckLogLevel(WARNING_LEVEL))
            {
                return;
            }

            this.iLog.Warning(string.Format(_message, _args));
        }

        public void Info(string _message, params object[] _args)
        {
            if (!CheckLogLevel(INFO_LEVEL))
            {
                return;
            }

            this.iLog.Info(string.Format(_message, _args));
        }

        public void Debug(string _message, params object[] _args)
        {
            if (!CheckLogLevel(DEBUG_LEVEL))
            {
                return;
            }

            this.iLog.Debug(string.Format(_message, _args));
        }

        public void Error(string _message, params object[] _args)
        {
            StackTrace st = new StackTrace(2, true);
            string s = string.Format(_message, _args) + '\n' + st;
            this.iLog.Error(s);
        }

        public void Console(string _message)
        {
            this.iLog.Debug(_message);
        }

        public void Console(string _message, params object[] args)
        {
            string s = string.Format(_message, args);
            this.iLog.Debug(s);
        }
    }
}